<template>
  <div class="card">
    <div style="display: flex; align-items: center; margin-bottom: 8px;">
      <span style="font-weight: bold;">监控区域</span>
      <!--      <el-button type="primary" size="small" style="margin-left: auto;" @click="openAddRoot">新增</el-button>-->
      <span class="iconRight" @click="openAddRoot">
        <i class="el-icon-plus"></i>新增
      </span>
    </div>
    <el-input v-model="search" placeholder="搜索点位名称" size="small" style="margin-bottom: 8px;" />
    <div class="tree-area">
      <div class="tree-scroll-wrapper">
        <el-tree ref="tree" class="scroll-tree" :data="treeData" :props="defaultProps" @node-click="handleNodeClick"
          node-key="id" :default-expand-all="true" :expand-on-click-node="false" :highlight-current="true"
          v-loading="loading" element-loading-text="加载中...">
          <span class="custom-tree-node" slot-scope="{ node, data }">
            <span>{{ data.label }}</span>
            <el-dropdown>
              <el-button icon="el-icon-edit" size="mini" type="text" @click="startEdit(data)" />
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>重命名</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
            <el-dropdown>
              <el-button icon="el-icon-more" size="mini" type="text"></el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item @click.native="openAddChild(node, data)">新增子区域</el-dropdown-item>
                <el-dropdown-item @click.native="moveNode(node, data, 'up')">上移</el-dropdown-item>
                <el-dropdown-item @click.native="moveNode(node, data, 'down')">下移</el-dropdown-item>
                <el-dropdown-item divided @click.native="removeNode(node, data)">删除</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </span>
        </el-tree>
      </div>
    </div>
    <!-- 空状态 -->
    <div v-if="!loading && treeData.length === 0" style="text-align: center; padding: 40px 0; color: #909399;">
      <i class="el-icon-folder-opened" style="font-size: 48px; margin-bottom: 16px;"></i>
      <p>暂无监控区域数据</p>
    </div>
    <!-- 弹窗-输入区域名称/重命名 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="300px" @close="handleDialogClose">
      <el-input v-model="dialogInput" placeholder="请输入区域名称" maxlength="20" />
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleDialogConfirm">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { addMonitorArea, getMonitorAreaTreeList, updateMonitorAreaName, deleteMonitorArea, moveMonitorArea } from '@/api/cameraManagement/cameraManagement'
export default {
  name: 'treeMenu',
  data() {
    return {
      treeData: [],
      allTreeData: [], // 完整树形
      search: '',
      editingId: null,
      editingLabel: '',
      loading: false,
      searchTimer: null,
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      dialogVisible: false,
      dialogTitle: '',
      dialogInput: '',
      dialogParentId: 0,
      dialogNode: null,
      dialogMode: '', // 新增: 'addRoot' | 'addChild'，重命名: 'edit'
      expandedKeys: []
    }
  },
  mounted() {
    this.getAllTreeData().then(() => {
      this.filterTree()
    })
  },
  beforeDestroy() {
    if (this.searchTimer) {
      clearTimeout(this.searchTimer)
    }
  },
  watch: {
    search: {
      handler() {
        this.filterTree()
      },
      immediate: false
    }
  },
  methods: {
    // 获取全部树数据
    async getAllTreeData() {
      this.loading = true
      try {
        const res = await getMonitorAreaTreeList({})
        if (res && res.code === 200 && res.data) {
          this.allTreeData = res.data
        } else {
          this.allTreeData = []
        }
      } finally {
        this.loading = false
      }
    },
    filterTreeData(tree, keyword) {
      //过滤掉 摄像头节点（type=2）
      const filterFn = (nodes) => {
        return nodes
          .filter(node => node.type !== '2')
          .map(node => {
            const children = node.children ? filterFn(node.children) : []
            return { ...node, children }
          })
      }
      const filteredTree = filterFn(tree)
      if (!keyword) return filteredTree
      return filteredTree
        .map(node => {
          const children = node.children ? this.filterTreeData(node.children, keyword) : []
          if ((node.label && node.label.indexOf(keyword) !== -1) || children.length) {
            return { ...node, children }
          }
          return null
        })
        .filter(Boolean)
    },
    filterTree() {
      const keyword = this.search.trim()
      this.treeData = this.filterTreeData(this.allTreeData, keyword)
      if (this.treeData.length > 0) {
        const firstNode = this.treeData[0]
        // 默认选中第一个节点
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(firstNode.id)
          this.handleNodeClick(firstNode)
        })
      }
    },
    //新增一级区域
    openAddRoot() {
      this.dialogTitle = '新增区域'
      this.dialogInput = ''
      this.dialogParentId = 0
      this.dialogNode = null
      this.dialogMode = 'addRoot'
      this.dialogVisible = true
    },
    // 新增子区域
    openAddChild(node, data) {
      this.dialogTitle = '新增子区域'
      this.dialogInput = ''
      this.dialogParentId = data.id
      this.dialogNode = data
      this.dialogMode = 'addChild'
      this.dialogVisible = true
    },
    // 重命名
    startEdit(data) {
      this.dialogTitle = '重命名区域'
      this.dialogInput = data.label
      this.dialogParentId = 0
      this.dialogNode = data
      this.dialogMode = 'edit'
      this.dialogVisible = true
    },
    // 弹窗统一处理
    async handleDialogConfirm() {
      if (!this.dialogInput.trim()) {
        this.$message.warning('请输入区域名称')
        return
      }
      if (this.dialogMode === 'addRoot' || this.dialogMode === 'addChild') {
        // 新增
        const params = {
          baseName: this.dialogInput.trim(),
          baseParentId: this.dialogParentId
        }
        try {
          const res = await addMonitorArea(params)
          if (res && res.code === 200) {
            this.$message.success('新增成功')
            this.dialogVisible = false
            await this.getAllTreeData()
            this.filterTree()
          } else {
            this.$message.error(res?.msg || '新增失败')
          }
        } catch (e) {
          this.$message.error('新增失败')
        }
      } else if (this.dialogMode === 'edit') {
        // 重命名
        const data = this.dialogNode
        if (this.dialogInput.trim() && this.dialogInput.trim() !== data.label) {
          try {
            const params = {
              baseId: data.id,
              baseName: this.dialogInput.trim()
            }
            const res = await updateMonitorAreaName(params)
            if (res && res.code === 200) {
              this.$message.success('更新成功')
            } else {
              this.$message.error(res?.msg || '更新失败')
            }
            this.dialogVisible = false
            await this.getAllTreeData()
            this.filterTree()
          } catch (error) {
            this.$message.error('更新失败')
            this.dialogVisible = false
            await this.getAllTreeData()
            this.filterTree()
          }
        } else {
          this.dialogVisible = false
        }
      }
    },
    // 节点单击事件
    handleNodeClick(data) {
      if (data && data.id) {
        this.$emit('node-click', data)
      }
    },
    //删除树形菜单项
    async removeNode(node, data) {
      try {
        await this.$confirm('确定删除该区域吗？', '提示', { type: 'warning' })
        const res = await deleteMonitorArea(data.id)
        if (res && res.code === 200) {
          this.$message.success('删除成功')
          await this.getAllTreeData()
          this.filterTree()
        } else {
          this.$message.error(res?.msg || '删除失败')
          await this.getAllTreeData()
          this.filterTree()
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除失败:', error)
          this.$message.error('删除失败')
          await this.getAllTreeData()
          this.filterTree()
        }
      }
    },
    //树形菜单移动
    async moveNode(node, data, dir) {
      const parent = node.parent
      const children = parent.data.children || this.treeData
      const idx = children.indexOf(data)

      if (dir === 'up' && idx > 0) {
        try {
          const params = {
            baseId: data.id,
            direction: "1"
          }
          const res = await moveMonitorArea(params)
          if (res && res.code === 200) {
            this.$message.success('移动成功')
            await this.getAllTreeData()
            this.filterTree()
          } else {
            this.$message.error(res?.msg || '移动失败')
          }
        } catch (error) {
          console.error('移动失败:', error)
          this.$message.error('移动失败')
        }
      }

      if (dir === 'down' && idx < children.length - 1) {
        try {
          const params = {
            baseId: data.id,
            direction: "2"
          }
          const res = await moveMonitorArea(params)
          if (res && res.code === 200) {
            this.$message.success('移动成功')
            await this.getAllTreeData()
            this.filterTree()
          } else {
            this.$message.error(res?.msg || '移动失败')
          }
        } catch (error) {
          console.error('移动失败:', error)
          this.$message.error('移动失败')
        }
      }
    },
    // 弹窗关闭时清理
    handleDialogClose() {
      this.dialogInput = ''
      this.dialogMode = ''
      this.dialogNode = null
      this.dialogParentId = 0
    }
  }
}
</script>

<style scoped>
.card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.tree-area {
  flex: 1 1 0%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.tree-scroll-wrapper {
  flex: 1 1 0%;
  min-height: 0;
  overflow-y: auto;
  overflow-x: auto;
  max-width: 100%;
}

.scroll-tree {
  display: table;
  width: auto;
  min-width: 0;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  padding: 2px 0;
  white-space: nowrap;
  flex-shrink: 0;
}

.custom-tree-node .el-button {
  margin-left: 8px;
  opacity: 0;
  transition: opacity 0.2s;
}

.custom-tree-node:hover .el-button {
  opacity: 1;
}

.custom-tree-node .el-input {
  margin-right: 8px;
}

.el-tree-node__content {
  padding: 8px 0;
}

.el-tree-node__content:hover {
  background-color: #f5f7fa;
}

.iconRight {
  font-family: Source Han Sans CN, Source Han Sans CN;
  font-weight: 400;
  font-size: 14px;
  color: #0088FF;
  margin-left: auto
}
</style>
